---@alias stamp string
---| 'superarmor' # 龙脊焚劫烩 霸体
---| 'respawn_after_death' # 死亡后3秒内重生

---@class ent
---@field _stamp_dst_lan netvar
---@field map_stamp_dst_lan table<string|stamp, true|nil>
---@field AddStamp fun(self,stamp:table<stamp,boolean>)
---@field RemoveStamp fun(self,stamp:string|stamp)
---@field HasStamp fun(self,stamp:table<stamp,boolean>):boolean
---@field q_stamp_dst_lan table<stamp,boolean>
---@field _taskintime_stamp_dst_lan Periodic|nil

---@param data string
---@return table<string, boolean>
local function decode_stamp(data)
    local result = {}

    for pair in string.gmatch(data, "[^;]+") do
        local name, flag = pair:match("^(.-)|([01])$")
        if name and flag then
            result[name] = (flag == "1")
        end
    end

    return result
end

AddPrefabPostInitAny(
---comment
---@param inst ent
function (inst)

    inst._stamp_dst_lan = net_string(inst.GUID, "_stamp_dst_lan.stamp", "_stamp_dst_lan.stamp.event")
    inst.map_stamp_dst_lan = {}
    inst.q_stamp_dst_lan = {}

    function inst:HasStamp(stamp)
        return inst.map_stamp_dst_lan[stamp] and true or false
    end

    function inst:AddStamp(stamp)
        inst.q_stamp_dst_lan[stamp] = true
        inst.map_stamp_dst_lan[stamp] = true

        if inst._taskintime_stamp_dst_lan then inst._taskintime_stamp_dst_lan:Cancel() inst._taskintime_stamp_dst_lan = nil end
        inst._taskintime_stamp_dst_lan = inst:DoTaskInTime(0, function()
            if inst and TheWorld then
                if TheWorld.ismastersim then
                    local parts = {}

                    for k, v in pairs(inst.q_stamp_dst_lan) do
                        table.insert(parts, k .. '|' .. (v and '1' or '0'))
                        inst.q_stamp_dst_lan[k] = nil
                    end

                    local _encode = table.concat(parts, ';')
                    inst._stamp_dst_lan:set(_encode)
                end
            end
        end)
    end

    function inst:RemoveStamp(stamp)
        inst.q_stamp_dst_lan[stamp] = false
        inst.map_stamp_dst_lan[stamp] = nil

        if inst._taskintime_stamp_dst_lan then inst._taskintime_stamp_dst_lan:Cancel() inst._taskintime_stamp_dst_lan = nil end
        inst._taskintime_stamp_dst_lan = inst:DoTaskInTime(0, function()
            if inst and TheWorld then
                if TheWorld.ismastersim then
                    local parts = {}

                    for k, v in pairs(inst.q_stamp_dst_lan) do
                        table.insert(parts, k .. '|' .. (v and '1' or '0'))
                        inst.q_stamp_dst_lan[k] = nil
                    end

                    local _encode = table.concat(parts, ';')
                    inst._stamp_dst_lan:set(_encode)
                end
            end
        end)
    end

    if not TheWorld.ismastersim then
        inst:ListenForEvent("_stamp_dst_lan.stamp.event", function(this, data)
            local res = inst._stamp_dst_lan:value()
            ---@cast res string
            local stamp_tbl = decode_stamp(res)
            for k,v in pairs(stamp_tbl) do
                inst.map_stamp_dst_lan[k] = v and true or nil
            end
        end)
        return inst
    end

end)

----------------
